# -*- coding: UTF-8 -*-
# @description : python
# @Author : zyl
# @Time : 2021/8/27 16:38
# @Remark:视频监控配置Server层
import json, xlwt, xlrd, math, os
import sys

from mxsoftpy import Server
from db.common.VideoManage.VideoMonitor.MonitorConfig import MonitorConfigDB
from model.common.VideoManage.VideoMonitor.MonitorConfig import MonitorConfigModel
from mxsoftpy.exception import ParamsError
from db.common.VideoManage.VideoMonitor.Group import GroupDB
from io import BytesIO
from pydantic import ValidationError


class MonitorConfigServer(Server):
    """
    视频监控配置Server层
    """
    __model__ = MonitorConfigModel
    __db__ = MonitorConfigDB

    def create(self, *args, **kwargs):
        """
        新增视频监控配置信息
        :param args:
        :param kwargs: 前台参数 字典
        :return: 添加得主键ID 字符串
        """
        return self.db.create(*args, **kwargs)

    def list(self, **kwargs):
        """
        监控配置列表
        :param kwargs:  前台参数字典
        :return: 配置列表
        """
        if 'page_size' not in kwargs:
            kwargs['page_size'] = 10
        if 'page_index' not in kwargs:
            kwargs['page_index'] = 1
        if 'order_by' not in kwargs:
            kwargs['order_by'] = 'MonitorNumber'
        if 'is_desc' not in kwargs:
            kwargs['is_desc'] = False
        else:
            if kwargs['is_desc'] == '0':
                kwargs['is_desc'] = True
            else:
                kwargs['is_desc'] = False  # 升序

        config_dict, config_Keys_list, dataCount_int = self.db.config_dict(**kwargs)
        print(config_Keys_list)
        # 获取所有分组
        Group_dict = GroupDB().group_dict()
        lReturn = list()
        for szkey in config_Keys_list:
            if szkey in config_dict:
                config_dict[szkey]['GroupName'] = Group_dict[str(config_dict[szkey]['GroupId'])]['GroupName']
                lReturn.append(config_dict[szkey])
        result = json.dumps(
            {'status': 'success', 'data': lReturn, 'page_index': kwargs['page_index'], 'pageSize': kwargs['page_size'],
             'dataCount': dataCount_int, 'pageCount': math.ceil(dataCount_int / int(kwargs['page_size']))})
        return result

    def delete(self, **kwargs):
        """
        删除监控配置
        :param kwargs: 参数字典
        :return: 删除得主键ID 字符串
        """
        return self.db.delete(kwargs['id'])

    def update(self, **kwargs):
        """
        修改监控配置
        :param kwargs: 前台参数字典
        :return:吸怪数据id 字符串
        """
        return self.db.update(kwargs['id'], **kwargs)

    def retrieve(self, **kwargs):
        """
        视频监控信息回显
        :param kwargs: 参数字典
        :return: 数据列表
        """
        return self.db.retrieve(kwargs['id'])

    def move(self, **kwargs):
        """
        批量移动
        :param kwargs: 参数字典
        :return:移动的主键ID 字符串
        """
        if 'GroupId' not in kwargs or len(kwargs['GroupId']) == 0:
            raise ParamsError('组不能为空')
        if 'ConfigId' not in kwargs or len(kwargs['GroupId']) == 0:
            raise ParamsError('监控不能为空')
        return self.db.move(**kwargs)

    def sort(self, **kwargs):
        """
        批量排序
        :param kwargs: 参数字典
        :return: 排序得主键ID 字符串
        """
        kwargs['data'] = json.loads(kwargs['data'])
        return self.db.sort(**kwargs)

    def set_style(self, color='white', height=150, bold=False, color_index=4):
        """
        设置单元格样式
        :param color:  颜色 字符串
        :param height:  高度 int
        :param bold:    布尔值
        :param color_index:    布尔值
        :return: 返回样式
        """
        # ： 设置单元格字体
        style = xlwt.XFStyle()
        font = xlwt.Font()
        # font.name = name
        font.bold = bold
        font.color_index = color_index
        font.height = height
        font.num_format_str = '#,##0.00'
        style.font = font

        # 设置单元格背景颜色
        pattern = xlwt.Pattern()
        pattern.pattern = xlwt.Pattern.SOLID_PATTERN
        pattern.pattern_fore_colour = xlwt.Style.colour_map[color]
        style.pattern = pattern

        #:设置单元格边框线条
        borders = xlwt.Borders()  # Create Borders
        # May be: NO_LINE, THIN, MEDIUM, DASHED, DOTTED, THICK, DOUBLE, HAIR,
        # MEDIUM_DASHED, THIN_DASH_DOTTED, MEDIUM_DASH_DOTTED,
        # THIN_DASH_DOT_DOTTED, MEDIUM_DASH_DOT_DOTTED,
        # SLANTED_MEDIUM_DASH_DOTTED, or 0x00 through 0x0D.
        borders.left = xlwt.Borders.THIN
        borders.right = xlwt.Borders.THIN
        borders.top = xlwt.Borders.THIN
        borders.bottom = xlwt.Borders.THIN
        style.borders = borders  # Add Borders to Style

        # ： 设置单元格居中格式
        alignment = xlwt.Alignment()  # Create Alignment
        # May be: HORZ_GENERAL, HORZ_LEFT, HORZ_CENTER, HORZ_RIGHT, HORZ_FILLED,
        # HORZ_JUSTIFIED, HORZ_CENTER_ACROSS_SEL, HORZ_DISTRIBUTED
        alignment.horz = xlwt.Alignment.HORZ_CENTER  # 横向居中
        alignment.vert = xlwt.Alignment.VERT_CENTER  # 纵向居中  May be: VERT_TOP, VERT_CENTER, VERT_BOTTOM, VERT_JUSTIFIED, VERT_DISTRIBUTED
        alignment.wrap = xlwt.Alignment.WRAP_AT_RIGHT  # ：自动换行
        style.alignment = alignment
        return style

    def download(self):
        """
        下载模板
        :return: 二进制文件数据
        """
        book = xlwt.Workbook(encoding='utf-8')
        sheet = book.add_sheet('sheetname')
        row_list = ['监控名称*', '分组*', '监控序号*', '用户名', '密码', '摄像头IP*', 'rtsp端口*', '通道号*', '摄像头方位', '服务器ip*']
        sheet.write_merge(0, 0, 0, 8, '视频监控', self.set_style('white', 250, True))
        #sheet.write_merge(1, 1, 0, 8, '请将单元格设置文本以免导入出错', self.set_style('red', 250, True))
       # sheet.write(1, 8, '请将单元格设置文本以免导入出错', self.set_style('red', 200, True))
        # 写入第二行数据
        for i in range(0, len(row_list)):
            sheet.write(1, i, row_list[i], self.set_style('sky_blue', 200, True, 3))

        sheet.col(0).width = 4000
        sheet.col(1).width = 4000
        sheet.col(2).width = 4000
        sheet.col(3).width = 2000
        sheet.col(4).width = 5000
        sheet.col(5).width = 3000
        sheet.col(6).width = 10000
        sheet.col(7).width = 10000
        sheet.col(8).width = 10000
        sheet.col(9).width = 3000
        sio = BytesIO()
        book.save(sio)
        return sio.getvalue()

    def ConfigImport(self, FilePath):
        """
        批量导入
        :param FilePath: 文件路径 字符串
        :return: 布尔值
        """
        try:
            data = xlrd.open_workbook(FilePath)  # 打开xls文件
            table = data.sheets()[0]  # 打开第一张表
            srows = table.nrows  # 获取表的行数
            args = ''
        except Exception:
                return False, '数据导入失败'

        error_str = ''
        config_dict = {'MonitorName': '监控名称', 'MonitorNumber': '监控序号', 'UserName': '用户名', 'pwd': '密码',
                       'CameraIp': '摄像头IP', 'RtspPort': 'rtsp端口', 'ChannelNumber': '通道号',
                       'CameraPosition': '摄像头方位', 'server_ip': '服务器ip'}
        group_dict = GroupDB().group_dict_name()
        success_int = 0
        kwargs = {}
        for i in range(2, srows):  # 循环逐行打印
            row_data = table.row_values(i)[:10]
            # 循环判断类型
            for si, val in enumerate(row_data):
                if table.cell(i, si).ctype == 2:
                    row_data[si] = int(table.cell(i, si).value)

            try:
                group_name = str(row_data[1])
                if group_name in group_dict:
                    group_id = int(group_dict[group_name])
                else:
                    raise Exception(group_name + ' 分组名称不存在')

                kwargs = {'MonitorName': str(row_data[0]), 'MonitorNumber': row_data[2], 'UserName': str(row_data[3]),
                          'pwd': str(row_data[4]), 'CameraIp': str(row_data[5]), 'RtspPort': row_data[6],
                          'ChannelNumber': str(row_data[7]), 'CameraPosition': str(row_data[8]),
                          'server_ip': str(row_data[9]), 'GroupId': group_id, 'is_import': 1}

                self.db.create(**self.model(*args, **kwargs).dict())
                success_int += 1
            except ValidationError:
                error_type, error_value, error_traceback = sys.exc_info()
                error_dict = [{' -> '.join(str(e) for e in error['loc']): error['msg']} for error in
                              error_value.errors()]
                for value in error_dict:
                    name = list(value.keys())[0]
                    err = list(value.values())[0]
                    if err == 'value is not a valid integer':
                        err = kwargs[name] + '必须是整数'
                    elif err == 'ensure this value has at least 1 characters':
                        err = kwargs[name] + '不能为空'
                    elif err == 'IPv4地址格式不正确':
                        err = kwargs[name] + 'IP地址格式不正确'
                    error_str += config_dict[name] + ': ' + err + '\n'
            except Exception as e:
                error_str += str(e) + '\n'

        os.remove(FilePath)
        if error_str:
            return False, "导入成功：%d条 \n %s" % (success_int, error_str)
        return True, '导入成功：%d条' % success_int
